fix(auth): remove unverified client-asserted OAuth identity branch + throttle callback#3866
Conversation
|
Warning Review limit reached
More reviews will be available in 47 minutes and 26 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (2)
WalkthroughRemoves the ChangesOAuth Callback Security Fix
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #3866 +/- ##
=======================================
Coverage 92.48% 92.48%
=======================================
Files 165 165
Lines 5400 5387 -13
Branches 1735 1730 -5
=======================================
- Hits 4994 4982 -12
+ Misses 326 325 -1
Partials 80 80
Flags with carried forward coverage won't be shown. Click here to find out more. Continue to review full report in Codecov by Harness.
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR hardens the OAuth flow in modules/auth by removing a client-controlled OAuth callback bypass that could mint a session without provider verification, and by applying existing rate-limiting to the OAuth initiation/callback routes.
Changes:
- Removes the
req.body.strategy === falseOAuth callback branch that trusted client-asserted identity data. - Applies
authLimiterto/api/auth/:strategyand/api/auth/:strategy/callback(GET + POST). - Replaces the prior “client-side OAuth callback” integration test with a regression test ensuring no
TOKENcookie is minted from a forged callback body.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| modules/auth/controllers/auth.controller.js | Deletes the insecure client-asserted identity branch and always delegates identity verification to Passport. |
| modules/auth/routes/auth.routes.js | Adds authLimiter to OAuth initiation and callback routes to reduce brute-force/enumeration risk. |
| modules/auth/tests/auth.integration.tests.js | Updates integration tests to cover the removed bypass with a security regression assertion. |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@modules/auth/tests/auth.integration.tests.js`:
- Around line 579-600: The UserService.create() call that creates the victim
user is currently outside the try/finally block, which means if an old user with
the same email exists from a previous test run, the create will fail with no
cleanup opportunity, causing flaky test failures. Move the victim user creation
inside the try block after its opening brace, and before creating the victim,
add a pre-cleanup step that attempts to remove any existing user with the
victimEmail (wrapped in a try-catch to ignore errors if the user doesn't exist).
This ensures the test starts with a clean state regardless of previous test
outcomes.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: abc1e8e2-65db-47cd-809e-60061bd3466e
📒 Files selected for processing (3)
modules/auth/controllers/auth.controller.jsmodules/auth/routes/auth.routes.jsmodules/auth/tests/auth.integration.tests.js
… clarify comment - Move victim UserService.create() inside try/finally to avoid flakiness on reruns (pre-delete any leftover oauthcb-victim@test.com first) - Replace fragile `status >= 400` with `not.toBe(200)` + no-TOKEN-cookie; the failure path may 302-redirect rather than return 4xx, so the real security invariant (no session minted) is now the hard assertion - Reword oauthCallback comment: passport.authenticate() does verify the provider response; the unsafe part was trusting a client-asserted body identity with no provider-token check (that branch is now removed)
Summary
req.body.strategy === false) that minted aTOKENsession cookie from a client-controlled identity without ever verifying a provider token. Any caller that posted a craftedstrategy=falsebody with an arbitrary email could log in as any user with zero provider involvement.authenticate(), which performs the actual provider-token verification before a session is issued.authLimiter(existing rate-limiter middleware) is applied to both the callback route and the OAuth initiation route, preventing brute-force enumeration of the former attack surface.strategy=falsebody payload is included, asserting the callback rejects without a valid provider token.Why
The removed branch was an unguarded escape hatch that let any HTTP client bypass the OAuth provider entirely and impersonate any account.
Scope
modules/authnonehighValidation
npm run lintnpm testGuardrails check
.env*,secrets/**, keys, tokens)Notes for reviewers
strategy===falsebranch had no legitimate use — it was a vestigial fast-path that bypassed the provider entirely.Closes #3849
Part of the security audit epic #3848
Summary by CodeRabbit
Release Notes
Security Fixes
Improvements